package com.navinfo.platform.trip.common.arithmetic;

import com.navinfo.platform.trip.common.arithmetic.data.CommonData;
import com.navinfo.platform.trip.common.arithmetic.data.OuterStatisticData;
import com.navinfo.platform.trip.common.arithmetic.var.VarCommon;
import com.navinfo.platform.trip.common.arithmetic.var.VarDrivingCity;
import com.navinfo.platform.trip.common.arithmetic.manager.AbstractArithmetic;
import com.navinfo.platform.trip.common.config.ConfigMap;
import com.navinfo.platform.trip.common.util.ArithmeticUtils;

import java.math.BigDecimal;

/**
 * 城市、非城市驾驶<br/>
 * 依赖{@link Mileage}里程油耗算法<br/>
 * 依赖{@link Brake}计算的行程刹车次数<br/>
 * 输出：统计<br/>
 */
public class DrivingCity extends AbstractArithmetic<VarDrivingCity> {
    /**
     * 行程时长阈值(毫秒)
     */
    private Integer cityTripTime = ConfigMap.getInteger("City_Trip_Threshold") ;
    /**
     * 城市行驶刹车次数阈值(次)
     */
    private Integer cityBrakeNumber =  ConfigMap.getInteger("City_Brake_Number");
    /**
     * 城市行驶平均速度阈值(M/S)
     */
    private Double cityAVGSpeed = ArithmeticUtils.speedKmhToMs(ConfigMap.getInteger("City_Avg_Speed"));


    @Override
    public void calculate() {
        logger.debug("===============城市、非城市驾驶算法开始===========");
        VarDrivingCity var = super.getObj();
        CommonData commonData = getCommonData();

        //累加里程
        double drivingMileage = var.getDrivingMileage() + commonData.getDffMileage();
        logger.debug("DrivingMileage:{},DffDistance:{},累加后:{}", var.getDrivingMileage(), commonData.getDffMileage(), drivingMileage);
        var.setDrivingMileage(drivingMileage);

        //累加油耗
        double drivingFuel = var.getDrivingFuel() + commonData.getDffFuel();
        logger.debug("drivingFuel:{},DffOil:{},累加后:{}", var.getDrivingFuel(), commonData.getDffFuel(), drivingFuel);
        var.setDrivingFuel(drivingFuel);

        //累加时长
        int drivingTime = var.getDrivingTime()+commonData.getDffTime();
        logger.debug("drivingTime:{},dffTime:{},累加后:{}", var.getDrivingTime(), commonData.getDffTime(), drivingTime);
        var.setDrivingTime(drivingTime);

        if ( var.getDrivingTime() >= cityTripTime) {
            double speedIncludeMis = BigDecimal.valueOf(var.getDrivingMileage()*1000).divide(BigDecimal.valueOf(var.getDrivingTime()), 2, BigDecimal.ROUND_HALF_UP).doubleValue();
            //刹车次数大于阈值或平均速度小于阈值为城市行驶
            if ((commonData.getBrakeNumber()-var.getPreBrakeNumber())> cityBrakeNumber || speedIncludeMis< cityAVGSpeed) {
                calcCityDriving(var);
            } else {
                calcRuralDriving(var);
            }

            //到时长阀值后，清空这段时间内的累加距离，油耗，时间,将刹车次数更新
            var.setDrivingTime(0);
            var.setDrivingMileage(0d);
            var.setDrivingFuel(0d);
            var.setPreBrakeNumber(commonData.getBrakeNumber());
            logger.debug("preBrakeNumber:{}", commonData.getBrakeNumber());
        }else if (commonData.isTripLastNode() && var.getDrivingTime()< cityTripTime) {
            //如果行程结束且时间小于时长阀值，将里程、油耗、时长累加到非城市中
            calcRuralDriving(var);
        }

        logger.debug("===============城市、非城市驾驶算法结束===========");
    }

    @Override
    public void collect(OuterStatisticData statisticDataOut) {
        VarDrivingCity var = super.getObj();
        VarCommon cityDriving = var.getCityDriving();
        statisticDataOut.setCityDrivingMileage(ArithmeticUtils.mileageMToM(cityDriving.getMileage()));
        statisticDataOut.setCityDrivingFuel(ArithmeticUtils.fuelMlToMl(cityDriving.getFuel()));
        statisticDataOut.setCityDrivingDuration(ArithmeticUtils.timeMsToSecond(cityDriving.getDuration()));

        VarCommon ruralDriving = var.getRuralDriving();
        statisticDataOut.setRuralDrivingMileage(ArithmeticUtils.mileageMToM(ruralDriving.getMileage()));
        statisticDataOut.setRuralDrivingFuel(ArithmeticUtils.fuelMlToMl(ruralDriving.getFuel()));
        statisticDataOut.setRuralDrivingDuration(ArithmeticUtils.timeMsToSecond(ruralDriving.getDuration()));
    }

    /**
     * 累加城市数据
     * @param var
     */
    private void calcCityDriving(VarDrivingCity var) {
        VarCommon cityDriving = var.getCityDriving();
        cityDriving.addMileage( var.getDrivingMileage());
        cityDriving.addFuel(var.getDrivingFuel());
        cityDriving.addDuration(var.getDrivingTime());
    }

    /**
     * 累加非城市数据
     */
    private void calcRuralDriving(VarDrivingCity var) {
        VarCommon ruralDriving = var.getRuralDriving();
        ruralDriving.addMileage( var.getDrivingMileage());
        ruralDriving.addFuel(var.getDrivingFuel());
        ruralDriving.addDuration(var.getDrivingTime());
    }
}
